#include<algorithm>
#include<iostream>
#include<string>
using namespace std;

#include"delegate.hpp"

using namespace lxzcore;


#define TEST_FUN1 void test_func(string str){cout<<__FUNCSIG__<<" :"<<str<<endl;}

class TestClass1
{
public:
	TEST_FUN1
};

class TestClass2
{
public:
	TEST_FUN1
};

TEST_FUN1

template<typename ...Args>
string getArgsName()
{
	const char* strs[] = { typeid(Args).name()... };
	 
	string ret_str="";
	 
	int count = sizeof(strs)/sizeof(char*);
	  
	for (int i = 0; i < count;i++)
	{ 
		ret_str += strs[i];
		if (i != count - 1)
			ret_str += " ";
	} 
	return ret_str;
}


template <typename  T>
struct FFFF;

template <typename R, typename C, typename... P>
struct FFFF<R(C::*)(P...)const>
{
	typedef R(Type)(P...);
};
 

template<typename F>
auto getFun(F&& f)-> decltype(std::function< FFFF<decltype(&F::operator())>::Type>(f))
{
	std::function< FFFF<decltype(&F::operator())>::Type>FFFFFF(f);

	return FFFFFF;
}

/////////////////////////

template <typename  T>
struct FFFFFFFFF;

template <typename R, typename C, typename... P>
struct FFFFFFFFF<R(C::*)(P...)const>
{
	typedef R(*Type)(P...);
};

template <typename R, typename C, typename... P>
struct FFFFFFFFF<R(C::*)(P...)>
{
	typedef R(*Type)(P...);
};
 
template<typename F>
auto getFunPtr(F& f)->decltype(FFFFFFFFF<decltype(&F::operator())>::Type)
{
	 FFFFFFFFF<decltype(&F::operator())>::Type ff = f;
	return ff;
}

int main(int, char**)
{ 
	
	//getFun( []()->void{});

	 cout << typeid(getFunPtr([]()->void{})).name() << endl;

	return 0;



	cout << getArgsName<int, int, double, char*>() << endl;
 

	delegate<void()> dele_test_;
	dele_test_ += []()->void{cout << "lambda delegate test1!" << endl; };
	dele_test_();


	cout << "------------------------------------"<<endl;

	TestClass1 tc1;
	TestClass1 tc11;
	TestClass2 tc2;

	delegate<void(string)> dele_test_1;
	dele_test_1 += makeDelHelpClass(&TestClass1::test_func, &tc1);
	dele_test_1 += makeDelHelpClass(&TestClass1::test_func, &tc11);
	dele_test_1 += makeDelHelpClass(&TestClass2::test_func, &tc2);
	dele_test_1 += test_func;
	dele_test_1( "delegate test .... 4");

	cout << "------------------------------------" << endl;
	dele_test_1 -= makeDelHelpClass(&TestClass1::test_func, &tc1);
	dele_test_1( "delegate test .... 3");

	cout << "------------------------------------" << endl;
	dele_test_1 -= makeDelHelpClass(&TestClass2::test_func, &tc2);
	dele_test_1( "delegate test ......2");

	cout << "------------------------------------" << endl;
	dele_test_1 -= test_func;
	dele_test_1( "delegate test ......1");
	return 0;
}

